package com.wlyuan.index.domain.index.builder;

import com.alibaba.fastjson.JSONObject;
import com.wlyuan.index.api.vo.OrderIndexSumVO;
import com.wlyuan.index.domain.index.utils.ExtractUtils;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import java.util.function.Consumer;

/**
 * @author yuanjie
 */
@Slf4j
public class OrderIndexSumBuilder {

    @Getter
    private enum Fields {
        totalWeight("totalWeight", "calculateWeight"),
        totalVolume("totalVolume", "calculateVolume"),
        totalValue("totalValue", "calculateValue"),
        totalQuantity("totalQuantity", "totalQuantity"),
        totalFee("totalFee", "totalFee"),
        size("size", "orderId");
        private final String name;
        private final String field;

        Fields(String name, String field) {
            this.name = name;
            this.field = field;
        }
    }


    static final AbstractAggregationBuilder<?>[] BUILDERS = new AbstractAggregationBuilder[]{
            AggregationBuilders.sum(Fields.totalWeight.getName()).field(Fields.totalWeight.getField()),
            AggregationBuilders.sum(Fields.totalQuantity.getName()).field(Fields.totalQuantity.getField()),
            AggregationBuilders.sum(Fields.totalVolume.getName()).field(Fields.totalVolume.getField()),
            AggregationBuilders.sum(Fields.totalValue.getName()).field(Fields.totalValue.getField()),
            AggregationBuilders.count(Fields.size.getName()).field(Fields.size.getField()),
    };

    private static void forEach(Consumer<AbstractAggregationBuilder<?>> consumer) {
        for (AbstractAggregationBuilder<?> builder : BUILDERS) {
            consumer.accept(builder);
        }
    }

    public SearchSourceBuilder build(SearchSourceBuilder sourceBuilder) {
        OrderIndexSumBuilder.forEach(sourceBuilder::aggregation);
        return sourceBuilder.size(0);
    }

    public OrderIndexSumVO collect(Aggregations aggregations) {
        JSONObject data = new JSONObject();
        ExtractUtils.fill(data, aggregations);
        return data.toJavaObject(OrderIndexSumVO.class);
    }
}
